package com.ecgsystem.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.achartengine.GraphicalView;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.app.LauncherActivity.ListItem;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ZoomButton;

import com.ecgsystem.constants.Constants;
import com.ecgsystem.graph.LineGraph;
import com.ecgsystem.graph.MyPoint;
import com.ecgsystem.listadapter.SignalListAdapter;
import com.ecgsystem.thread.ThreadGetSignalByFrame;
import com.ecgsystem.R;

public class OfflineECG extends Activity implements Runnable, Constants {

	public static int HEIGHT = 0;
	public static int WIDTH = 0;
	private static GraphicalView view[];
	private GraphicalView leadView[];
	private LineGraph lead[];
	private LineGraph lead2[];
	// private LineGraph ulead[];
	protected double minX[];
	protected double maxX[];
	protected double minY[];
	protected double maxY[];
	private double width = 1500;
	private static Thread thread;

	private ScrollView verticalView;
	private HorizontalScrollView horizotalView;
	private LinearLayout wrapLayout[];
	private LinearLayout popupLayout;
	private LinearLayout buttonLayout;
	private LinearLayout backButtonLayout;
	private LinearLayout leadLayout;
	private android.widget.LinearLayout.LayoutParams panelParam;

	private View currentSelectedView;
	public static boolean firstTimeStartup = true;
	int defaultPos = 0;
	
	private double i = 0;
	public static int loaded = 0;

	PopupWindow popUp;
	LinearLayout.LayoutParams leadParam;

	private double zoomRate = 1.2;
	private double zoom = 1;
	private double zoom2 = 1;

	public static ConcurrentLinkedQueue<Float>[] QueueDraw;
	public static boolean startDraw = false;
	public static boolean _run = false;
	DisplayMetrics metrics;

	private static Context context;
	private String recordID;
	private String uSignalID;
	private String comment;
	Intent intent;

	private Thread waitThread;
	protected GestureDetector mGesDetect;
	protected boolean isTapped;
	private static ProgressDialog m_ProgressDialog;

	public static Handler handler;

	// private Spinner unusalSignalSpinner;
	private ArrayList<HashMap<String, String>> signals;
	private ListView unusualSignal_ListView;
	private EditText id_search_ET;
	private Button showListBT;
	private SignalListAdapter signalAdapter;
	private Dialog unusualDialog = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// requestWindowFeature(Window.FEATURE_NO_TITLE);

		this.setContentView(R.layout.main);

		context = this;
		intent = this.getIntent();
		recordID = intent.getStringExtra(TAG_RECORD_ID);
		uSignalID = intent.getStringExtra(TAG_UNUSUALSIGNAL_ID);
		startDraw = false;
		_run = true;

		metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);

		HEIGHT = metrics.heightPixels;
		WIDTH = metrics.widthPixels;

		mGesDetect = new GestureDetector(this, new DoubleTapGestureDetector());

		// Progress Dialog
		m_ProgressDialog = new ProgressDialog(this);
		m_ProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		m_ProgressDialog.setMessage("Loading...");
		m_ProgressDialog.show();

		ZoomButton zoomInBT = (ZoomButton) findViewById(R.id.zoomPlusButton);
		zoomInBT.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				zoom = zoom / zoomRate;
				applyZoom(1);
			}
		});
		ZoomButton zoomOutBT = (ZoomButton) findViewById(R.id.zoomMinusButton);
		zoomOutBT.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				zoom = zoom * zoomRate;
				applyZoom(1);
			}
		});

		popUp = new PopupWindow(this);

		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

		// ************Man hinh popup hien thi 1 dao trinh ***************

		popupLayout = createPopUp();

		popUp.setContentView(popupLayout);

		createPanel();

		verticalView = (ScrollView) findViewById(R.id.scrollView);
		horizotalView = (HorizontalScrollView) findViewById(R.id.horizontalScrollView);
		horizotalView.setAlwaysDrawnWithCacheEnabled(true);
		horizotalView.setAnimationCacheEnabled(true);
		horizotalView.setSmoothScrollingEnabled(false);
		verticalView.setSmoothScrollingEnabled(false);

		maxX = new double[12];
		minX = new double[12];
		maxY = new double[12];
		minY = new double[12];

		thread = new Thread() {
			public void run() {
				Looper.prepare();
				_run = true;
				
				while (!startDraw) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				uiCallback.sendEmptyMessage(0);
				m_ProgressDialog.dismiss();
			}
		};
		thread.start();

		this.waitThread = new Thread(this);
		this.waitThread.start();
		
		showListBT = (Button) findViewById(R.id.button_show_unusualSignalList);
	}

	private int getPosbyID(String uSignalID) {
		HashMap<String, String> item;
		for (int i = 0; i < signals.size(); i++) {
			item = signals.get(i);
			if (item.get(Constants.TAG_UNUSUALSIGNAL_ID).equals(uSignalID)) {
				return i ;
			}
		}
		return 0;
	}

	private Dialog createDialog() {
		Dialog dialog = new Dialog(this);
		dialog.setTitle("C??��c ??��蘯?�n b蘯?�t th??��盻拵g");
		dialog.setContentView(R.layout.unusual_signal_list);

		unusualSignal_ListView = (ListView) dialog
				.findViewById(R.id.listView_unusualSignals);
		unusualSignal_ListView.setTextFilterEnabled(true);

		if (signals != null) {
			signalAdapter = new SignalListAdapter(OfflineECG.this, signals, defaultPos);
			unusualSignal_ListView.setAdapter(signalAdapter);
		}
		unusualSignal_ListView
				.setOnItemClickListener(new OnItemClickListener() {

					public void onItemClick(AdapterView<?> l, View v,
							int pos, long arg3) {
						refreshPanel(pos);
						unusualDialog.dismiss();
						if (firstTimeStartup) {// first time  highlight first row
							currentSelectedView = l.getChildAt(defaultPos);
						}
						firstTimeStartup = false; 
						if (currentSelectedView != null
								&& currentSelectedView != v) {
							currentSelectedView
									.setBackgroundColor(Color.TRANSPARENT);
						}

						currentSelectedView = v;
						currentSelectedView.setBackgroundColor(Color.DKGRAY);
					}
				});

		id_search_ET = (EditText) dialog
				.findViewById(R.id.editText_unusualSignals_id);
		id_search_ET.addTextChangedListener(new TextWatcher() {

			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				// TODO Auto-generated method stub

			}

			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub

			}

			public void afterTextChanged(Editable s) {
				if (signalAdapter != null) {
					signalAdapter.getFilter().filter(s);
				}
			}
		});
		return dialog;
	}

	protected void refreshPanel(int pos) {
		int minX = 0, maxX = 0;
		int start = Integer.valueOf(signals.get(pos).get(TAG_START_TIME));
		int end = Integer.valueOf(signals.get(pos).get(TAG_END_TIME));

		int w = (int) (width * zoom);
		if (end - start > w) {
			minX = start - 5;
			maxX = end + 5;
		} else {
			minX = (end + start - w) / 2;
			maxX = (end + start + w) / 2;
		}
		//if (popUpFlag == false) {
			for (int i = 0; i < 12; i++) {
				if (ThreadGetSignalByFrame.hasRecord[i]) {
					lead[i].getmRenderer().setRange(
							new double[] { minX, maxX, minY[i], maxY[i] });
					lead2[i].getmRenderer().setRange(
							new double[] { minX, maxX, minY[i], maxY[i] });

					lead[i].clearSeries2();
					lead[i].displayRED(start, end);

					lead2[i].clearSeries2();
					lead2[i].displayRED(start, end);

					view[i].repaint();
					leadView[i].repaint();

				}
			}
		/*} else {
			for (int i = 0; i < 12; i++) {
				if (ThreadGetSignalByFrame.hasRecord[i]) {
					lead2[i].getmRenderer().setRange(
							new double[] { minX, maxX, minY[i], maxY[i] });

					lead2[i].clearSeries2();
					lead2[i].displayRED(start, end);

					leadView[i].repaint();
				}
			}
		}*/
	}

	private void createPanel() {
		wrapLayout = new LinearLayout[3];
		wrapLayout[0] = (LinearLayout) findViewById(R.id.view1);
		wrapLayout[1] = (LinearLayout) findViewById(R.id.view2);
		wrapLayout[2] = (LinearLayout) findViewById(R.id.view3);

		view = new GraphicalView[12];
		leadView = new GraphicalView[12];
		lead = new LineGraph[12];
		lead2 = new LineGraph[12];

		panelParam = new LinearLayout.LayoutParams(
				android.view.ViewGroup.LayoutParams.MATCH_PARENT,
				android.view.ViewGroup.LayoutParams.MATCH_PARENT);
		panelParam.height = 250;
		panelParam.width = 400;

		leadParam = new LinearLayout.LayoutParams(
				android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
				android.view.ViewGroup.LayoutParams.WRAP_CONTENT);

		for (int j = 0; j < 12; j++) {
			lead[j] = new LineGraph(Constants.TYPE_ECG[j]);
			view[j] = lead[j].getView(this);

			view[j].setLayoutParams(panelParam);

			view[j].setDrawingCacheEnabled(true);
			view[j].setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

			wrapLayout[j % 3].addView(view[j]);

			lead2[j] = new LineGraph(Constants.TYPE_ECG[j]);
			leadView[j] = lead2[j].getView(this);
			leadView[j].setLayoutParams(leadParam);

			view[j].setOnTouchListener(new OnTouchListener() {

				public boolean onTouch(View v, MotionEvent event) {
					mGesDetect.onTouchEvent(event);
					if (isTapped) {
						for (int i = 0; i < 12; i++) {
							if (view[i] == v) {

								leadLayout.removeAllViews();
								leadLayout.addView(leadView[i]);

								double minx = lead[i].getDataset().getMinX() - 100;
								double maxx = lead[i].getDataset().getMaxX() + 100;
								double miny = lead[i].getDataset().getMinY() - 0.15;
								double maxy = lead[i].getDataset().getMaxY() + 0.15;
								lead[i].getmRenderer()
										.setPanLimits(
												new double[] { minx, maxx,
														miny, maxy });

								popUp.showAtLocation(verticalView,
										Gravity.CENTER, 0, 0);
								popUp.update(WIDTH, HEIGHT);
							}
						}
					}
					isTapped = false;
					return true;
				}
			});

			handler = new Handler();
		}
	}

	private LinearLayout createPopUp() {
		ImageButton backBT = new ImageButton(this);
		backBT.setImageResource(R.drawable.close);
		backBT.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {

				popUp.dismiss();
			}
		});

		ZoomButton plusBT = new ZoomButton(this);
		plusBT.setImageResource(android.R.drawable.btn_plus);
		plusBT.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {
				zoom2 = zoom2 / zoomRate;
				applyZoom(2);
			}
		});

		ZoomButton minusBT = new ZoomButton(this);
		minusBT.setImageResource(android.R.drawable.btn_minus);
		minusBT.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {
				zoom2 = zoom2 * zoomRate;
				applyZoom(2);
			}
		});

		Button showBT = new Button(this);
		showBT.setText("Unusual Signals");
		showBT.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				unusualDialog.show();
			}
		});

		// spinner = new Spinner(this);

		LinearLayout fullScreenLayout = new LinearLayout(this);
		fullScreenLayout.setOrientation(LinearLayout.VERTICAL);
		// fullScreenLayout.setGravity(Gravity.CENTER);
		fullScreenLayout.setLayoutParams(new LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

		buttonLayout = new LinearLayout(this);
		buttonLayout.setGravity(Gravity.LEFT);
		buttonLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.WRAP_CONTENT));

		backButtonLayout = new LinearLayout(this);
		// backButtonLayout.setOrientation(LinearLayout.HORIZONTAL);
		backButtonLayout.setGravity(Gravity.RIGHT);
		backButtonLayout.setLayoutParams(new LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

		// backButtonLayout.addView(spinner);
		backButtonLayout.addView(backBT);
		buttonLayout.addView(plusBT);
		buttonLayout.addView(minusBT);
		buttonLayout.addView(showBT);

		buttonLayout.addView(backButtonLayout);

		leadLayout = new LinearLayout(this);
		leadLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT));

		fullScreenLayout.addView(buttonLayout);

		fullScreenLayout.addView(leadLayout);

		return fullScreenLayout;
	}

	@Override
	protected void onStart() {
		super.onStart();
		Toast.makeText(context, "蘯?�n Menu ??��ｻ?�xem th??��ng tin chi ti蘯?�t b蘯?�n ghi",
				Toast.LENGTH_LONG).show();
	}

	@Override
	protected void onRestart() {
		super.onRestart();
	}

	@Override
	protected void onResume() {
		super.onResume();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);

		getWindowManager().getDefaultDisplay().getMetrics(metrics);

		HEIGHT = metrics.heightPixels;
		WIDTH = metrics.widthPixels;
		try {
			popUp.update(WIDTH, HEIGHT);
		} catch (NullPointerException e) {
		}
	}

	private Handler uiCallback = new Handler() {
		public void handleMessage(Message msg) {
			// tao diem
			try {
				for (int j = 0; j < QueueDraw[0].size(); j++, i = i + 2f) {
					for (int k = 0; k < 12; k++) {
						// QueueDraw[k].remove();
						// QueueDraw[k].remove();
						MyPoint p = new MyPoint(i, QueueDraw[k].remove());
						lead[k].addNewPoints(p);
						lead2[k].addNewPoints(p);
					}
				}
				applyZoom(1);
				signals = MainActivity.conn.getUnusualSignalOfRecord(recordID);
				if (uSignalID != null && !uSignalID.equals("")) {
					// tim vi tri doan bat thuong trong danh sach
					defaultPos = getPosbyID(uSignalID);
				}
				refreshPanel(defaultPos);
				unusualDialog = createDialog();
				showListBT.setOnClickListener(new OnClickListener() {
					public void onClick(View v) {
						unusualDialog.setCancelable(true);
						unusualDialog.setCanceledOnTouchOutside(true);
						unusualDialog.show();
					}
				});
			} catch (NoSuchElementException ex) {
				ex.printStackTrace();
				_run = false;
				applyZoom(1);
			}
		};
	};
	private ThreadGetSignalByFrame _thread;

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		super.onKeyDown(keyCode, event);
		switch (keyCode) {
		case KeyEvent.KEYCODE_BACK:
			startDraw = false;
			_run = false;
			_thread.shutdown();
			break;
		case KeyEvent.KEYCODE_MENU:
			// Popup Patient and record info // custom dialog final Dialog
			final Dialog dialog = new Dialog(context);
			dialog.setContentView(R.layout.custom_dialog);
			dialog.setTitle("Th??��ng tin chi ti蘯?�t");

			// set the custom dialog components - text, image and button
			TextView tvPatientName = (TextView) dialog
					.findViewById(R.id.textView_dia_patientName);
			tvPatientName.setText(intent.getStringExtra(TAG_PATIENT_NAME));
			TextView tvPatientID = (TextView) dialog
					.findViewById(R.id.textView_dia_patientID);
			tvPatientID.setText(intent.getStringExtra(TAG_PATIENT_ID));
			TextView tvRecordID = (TextView) dialog
					.findViewById(R.id.textView_dia_recordID);
			tvRecordID.setText(recordID);
			TextView tvRecordDate = (TextView) dialog
					.findViewById(R.id.textView_dia_date);
			String date = intent.getStringExtra(TAG_RECORD_DATE);
			tvRecordDate.setText(date.replaceAll("T", "\n"));

			final EditText edComment = (EditText) dialog
					.findViewById(R.id.editText_dia_comment);
			edComment.setText(comment);

			Button dialogOKButton = (Button) dialog
					.findViewById(R.id.button_dia_submit);
			dialogOKButton.setOnClickListener(new OnClickListener() {

				public void onClick(View arg0) {
					String content = edComment.getText().toString().trim();
					if (content != null && !content.equals("")
							&& comment == null) {
						if (MainActivity.conn.addNewComment(recordID,
								MainActivity.conn.realID, content).equals("1")) {
							dialog.dismiss();
							comment = content;
							edComment.setText(content);
						}
					} else if (content != null && !content.equals("")
							&& !content.equals(comment)) {
						if (MainActivity.conn.editComment(recordID,
								MainActivity.conn.realID, content).equals("1")) {
							dialog.dismiss();
							comment = content;
							edComment.setText(content);
						}
					}
				}
			});

			Button dialogCancelButton = (Button) dialog
					.findViewById(R.id.button_dia_cancel);
			dialogCancelButton.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					dialog.dismiss();
				}
			});

			dialog.show();
			break;
		}
		return true;
	}

	private void applyZoom(int type) {
		if (type == 1)
			for (int i = 0; i < 12; i++) {
				if (ThreadGetSignalByFrame.hasRecord[i]) {
					minX[i] = lead[i].getDataset().getMinX();
					maxX[i] = minX[i] + width * zoom;
					maxY[i] = lead[i].getDataset().getMaxY() * zoom;
					minY[i] = lead[i].getDataset().getMinY();

					lead[i].getmRenderer()
							.setRange(
									new double[] { minX[i], maxX[i], minY[i],
											maxY[i] });
					view[i].repaint();
				}
			}
		else if (type == 2)
			for (int i = 0; i < 12; i++) {
				if (ThreadGetSignalByFrame.hasRecord[i]) {
					minX[i] = lead[i].getDataset().getMinX();
					maxX[i] = minX[i] + width * zoom2;
					maxY[i] = lead[i].getDataset().getMaxY() * zoom2;
					minY[i] = lead[i].getDataset().getMinY();

					lead2[i].getmRenderer()
							.setRange(
									new double[] { minX[i], maxX[i], minY[i],
											maxY[i] });
					leadView[i].repaint();

				}
			}
	}

	class DoubleTapGestureDetector extends
			GestureDetector.SimpleOnGestureListener {

		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			Log.d("TAG", "Single Tap Detected ...");
			isTapped = true;
			return true;
		}

	}

	public boolean onTouch(View v, MotionEvent event) {
		if (v == verticalView) {
			return true;
		}
		if (v == horizotalView) {
			return true;
		}

		return true;
	}

	public static void displayAlert(final String mess) {
		handler.post(new Runnable() {
			public void run() {
				Toast.makeText(context, mess, Toast.LENGTH_LONG).show();
			}
		});
	}

	public void run() {
		Looper.prepare();
		_thread = new ThreadGetSignalByFrame(recordID);
		_thread.start();
	}

	static Handler progressHandler = new Handler() {
		public void handleMessage(Message msg) {
			m_ProgressDialog.incrementProgressBy(msg.what);
		}
	};

	public static void incrementLoadedPercent(int j) {
		progressHandler.sendEmptyMessage(j);
	}
}